package com.example.cloudpracticeplatform.service.impl;

import com.example.cloudpracticeplatform.common.Response;
import com.example.cloudpracticeplatform.entity.Course;
import com.example.cloudpracticeplatform.entity.Enrollment;
import com.example.cloudpracticeplatform.entity.ExperimentContainer;
import com.example.cloudpracticeplatform.service.CourseService;
import com.example.cloudpracticeplatform.service.DockerService;
import com.example.cloudpracticeplatform.service.EnrollmentService;
import com.example.cloudpracticeplatform.service.ExperimentContainersService;
import com.example.cloudpracticeplatform.utils.DockerUtils;
import com.example.cloudpracticeplatform.utils.RedisUtil;
import com.github.dockerjava.api.command.CreateContainerResponse;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.time.LocalDateTime;
import java.util.UUID;

@Service
@Slf4j
public class DockerServiceImpl implements DockerService {
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private CourseService courseService;
    
    @Resource
    private EnrollmentService enrollmentService;
    
    @Resource
    private ExperimentContainersService experimentContainersService;
    
    //创建镜像
    @Override
    public Response createImage(Integer courseId) {
        try {
            // 根据课程 ID 获取课程信息
            Course course = courseService.getCourseById(courseId);
            if (course == null) {
                return Response.error("没有找对课程信息，courseId: " + courseId);
            }
            if (course.getImageId() != null) {
                return Response.error("该镜像已被加载，courseId: " + courseId);
            }

            // 获取镜像路径并解码
            String imagePath = course.getImagePath();
            if (imagePath == null || imagePath.isEmpty()) {
                return Response.error("没有找到该镜像，courseId: " + courseId);
            }
            String decodedImagePath = URLDecoder.decode(imagePath, "UTF-8");

            // 提取文件名部分，确保兼容不同操作系统路径分隔符
            String fileName = decodedImagePath.substring(decodedImagePath.lastIndexOf("/") + 1);

            // 构造 MinIO 挂载路径和完整文件路径
            String minioMountPath = "/opt/minio/data/public";
            String imageFilePath = minioMountPath + "/" + fileName;

            // 使用 docker load 命令
            ProcessBuilder processBuilder = new ProcessBuilder(
                    "docker", "load", "-i", imageFilePath
            );
            Process process = processBuilder.start();

            // 读取命令输出
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(process.getInputStream()))) {
                String line;
                String imageId = null;
                while ((line = reader.readLine()) != null) {
                    if (line.startsWith("Loaded image ID: sha256:")) {
                        imageId = line.substring(line.indexOf("sha256:") + 7).trim();
                        break;
                    }
                }

                if (imageId != null) {
                    // 更新镜像 ID
                    courseService.updateImageId(courseId, imageId);
                } else {
                    return Response.error("未能获取到镜像 ID，courseId: " + courseId);
                }
            }

            return Response.success("镜像加载成功");
        } catch (Exception e) {
            e.printStackTrace();
            return Response.error("镜像加载失败: " + e.getMessage());
        }
    }

    //创建容器
    @Override
    public Response<ExperimentContainer> createAndStartContainer(Integer studentId, Integer courseId) {
        try {
            Enrollment enrollment = enrollmentService.findEnrollment(studentId, courseId);
            Course course = courseService.getCourseById(courseId);
            ExperimentContainer experimentContainer = new ExperimentContainer();
            experimentContainer.setEnrollmentId(enrollment.getEnrollmentId());
            //获取动态端口号
            String port = String.valueOf(redisUtil.leftPop("portList"));
            int portInt = Integer.parseInt(port);
            //生成账号密码
            String username="student"+studentId+ UUID.randomUUID().toString().replace("-", "").substring(0,8);
            String password=UUID.randomUUID().toString().replace("-", "");
            //创建容器
            CreateContainerResponse response = DockerUtils.createContainer(course.getImageId(),portInt,username,password);
            //启动容器
            DockerUtils.startContainer(response.getId());
            experimentContainer.setDockerContainerId(response.getId());
            experimentContainer.setAddress("https://47.116.32.173:"+port);
            experimentContainer.setUsername(username);
            experimentContainer.setPassword(password);
            LocalDateTime now = LocalDateTime.now();
            experimentContainer.setStartTime(now);
            experimentContainer.setEndTime(now);
            experimentContainer.setStatus("0");
            experimentContainersService.insert(experimentContainer);
            return Response.success(experimentContainer);
        } catch (Exception e) {
            log.error("创建容器失败，error:",e);
            return Response.error("创建容器失败");
        }
    }

    @Override
    public Response stopAndDelContainer(Integer studentId, Integer courseId) {
        try {
            Enrollment enrollment = enrollmentService.findEnrollment(studentId, courseId);
            ExperimentContainer experimentContainer = experimentContainersService.findByEnrollmentId(enrollment.getEnrollmentId());
            String containerId = experimentContainer.getDockerContainerId();
            DockerUtils.stopContainer(containerId);
            DockerUtils.removeContainer(containerId);
            //更新容器状态
            ExperimentContainer newExperimentContainer = new ExperimentContainer();
            newExperimentContainer.setContainerId(experimentContainer.getContainerId());
            newExperimentContainer.setEndTime(LocalDateTime.now());
            newExperimentContainer.setStatus("1");
            experimentContainersService.update(newExperimentContainer);
            //还回端口号
            redisUtil.rightPush("portList",experimentContainer.getAddress().substring(experimentContainer.getAddress().lastIndexOf(":")+1));
            return Response.success("停止容器成功");
        } catch (Exception e) {
            log.error("停止容器失败，error:",e);
            return Response.error("停止容器失败");
        }
    }

    @Override
    public Response rebuildContainer(Integer studentId, Integer courseId) {
        try {
            
            Enrollment enrollment = enrollmentService.findEnrollment(studentId, courseId);
            ExperimentContainer experimentContainer = experimentContainersService.findByEnrollmentId(enrollment.getEnrollmentId());
            if("0".equals(experimentContainer.getStatus())){
                //先停止并删除正在运行的容器
                String containerId = experimentContainer.getDockerContainerId();
                DockerUtils.stopContainer(containerId);
                DockerUtils.removeContainer(containerId);
            }
            //还回端口号
            redisUtil.rightPush("portList",experimentContainer.getAddress().substring(experimentContainer.getAddress().lastIndexOf(":")+1));
            //重新构建新的容器
            Course course = courseService.getCourseById(courseId);
            ExperimentContainer newExperimentContainer = new ExperimentContainer();
            newExperimentContainer.setContainerId(experimentContainer.getContainerId());
            //获取动态端口号
            String port = String.valueOf(redisUtil.leftPop("portList"));
            int portInt = Integer.parseInt(port);
            //生成账号密码
            String username="student"+studentId+ UUID.randomUUID().toString().replace("-", "").substring(0,8);
            String password=UUID.randomUUID().toString().replace("-", "");
            //创建容器
            CreateContainerResponse response = DockerUtils.createContainer(course.getImageId(),portInt,username,password);
            //启动容器
            DockerUtils.startContainer(response.getId());
            newExperimentContainer.setDockerContainerId(response.getId());
            newExperimentContainer.setAddress("https://47.116.32.173:"+port);
            newExperimentContainer.setUsername(username);
            newExperimentContainer.setPassword(password);
            experimentContainersService.update(newExperimentContainer);
            return Response.success("重建容器成功");
            
        } catch (Exception e) {
            return Response.error("重建容器失败");
        }
    }
    
    


}